package com.maixy.studyonlineapi.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.maixy.studyonlineapi.bean.Page;
import com.maixy.studyonlineapi.entity.Auth;
import com.maixy.studyonlineapi.entity.User;
import com.maixy.studyonlineapi.exceptions.TipException;
import com.maixy.studyonlineapi.mapper.AuthMapper;
import com.maixy.studyonlineapi.result.PageData;
import com.maixy.studyonlineapi.utils.LocalDateTimeUtils;
import com.maixy.studyonlineapi.view.AuthView;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @Classname AuthService
 * @Description TODO
 * @Date 2020/11/15 19:05
 * @Author by maixy
 */
@Service
public class AuthService extends BaseMPlusService<Auth, Long>{

    private final AuthMapper authMapper;

    @Resource
    private TeamService teamService;

    @Resource
    private ActivityService activityService;

    @Resource
    private UserService userService;

    protected AuthService(AuthMapper authMapper) {
        super(Auth.class, authMapper);
        this.authMapper = authMapper;
    }

    /**
     * 是否已报名
     * @param userId 用户id
     * @param activityId 活动id
     * @return java.lang.Boolean
     */
    public Boolean hasAuth(Long teamId, Long userId, Long activityId) {
        boolean hasAuth = false;
        if (teamService.hasActivityPower(teamId, userId, activityId)) {
            return true;
        }else {
            Auth auth = findAuthByUserIdAndActivityId(userId, activityId);
            if (null != auth && !auth.getHasDelete()) {
                hasAuth = true;
            }
        }
        return hasAuth;
    }


    /**
     * 报名活动
     * @param userId 用户id
     * @param activityId 活动id
     * @param teamId 团队id
     */
    public void authActivity(Long teamId, Long userId, Long activityId) {
        if (hasAuth(teamId, userId, activityId)) {
            throw new TipException("您已经是班级成员或班级管理员，无法再报名");
        }
        Auth auth = new Auth();
        auth.setCreateBy(userId);
        auth.setCreateTime(System.currentTimeMillis());
        auth.setHasDelete(false);
        auth.setActivityId(activityId);
        create(auth);
    }

    /**
     * 踢出班级成员
     *
     * @param teamId 团队id
     * @param userId 用户id
     * @param activityId 活动id
     * @param currentUserId 被踢出的用户id
     */
    public void kickOut(Long teamId, Long userId, Long activityId, Long currentUserId) {
        if (!teamService.hasPower(teamId, userId)) {
            throw new TipException("您没有权限踢出学员");
        }
        Auth auth = findAuthByUserIdAndActivityId(currentUserId, activityId);
        if (null == auth || auth.getHasDelete()) {
            throw new TipException("班级中没有此成员");
        }
        auth.setHasDelete(true);
        auth.setUpdateBy(System.currentTimeMillis());
        auth.setUpdateBy(userId);
        update(auth);
    }

    /**
     * 退出班级
     *
     * @param userId 用户id
     * @param activityId 活动id
     */
    public void quit(Long userId, Long activityId) {
        Auth auth = findAuthByUserIdAndActivityId(userId, activityId);
        if (null == auth || auth.getHasDelete()) {
            throw new TipException("您不在此班级中");
        }
        if (!auth.getCreateBy().equals(userId)) {
            throw new TipException("非本人操作,无法退出课程");
        }
        auth.setHasDelete(true);
        auth.setUpdateTime(System.currentTimeMillis());
        auth.setUpdateBy(userId);
        update(auth);
    }

    /**
     * 课程报名列表
     *
     * @param activityId 课程id
     * @param page 页面信息
     * @return PageData<com.maixy.studyonlineapi.view.AuthView>
     */
    public PageData<AuthView> getAuthList(Long activityId, Page page) {
        page.setHasMore(false);
        PageData<AuthView> pageData = new PageData<>();
        pageData.setPage(page);
        pageData.setData(Collections.emptyList());
        int beginIndex = (page.getPage() - 1) * page.getSize();
        List<Auth> authList = authMapper.getAuthList(activityId, beginIndex, page.getSize() + 1);
        if (CollectionUtils.isEmpty(authList)) {
            return pageData;
        }
        if (authList.size() > page.getSize()) {
            page.setHasMore(true);
            authList.remove(authList.size() - 1);
        }

        List<AuthView> authViewList = new ArrayList<>();
        for (Auth auth : authList) {
            authViewList.add(convert(auth));
        }
        pageData.setData(authViewList);

        return pageData;
    }

    /**
     * 报名视图转换
     *
     * @param auth 报名实体
     * @return com.maixy.studyonlineapi.view.AuthView
     */
    private AuthView convert(Auth auth) {
        AuthView view = new AuthView();
        User user = userService.findById(auth.getCreateBy());
        if (null == user || user.getHasDelete()) {
            return null;
        }
        view.setUserView(userService.convert(user));
        view.setCreateTimeStr(LocalDateTimeUtils.format(auth.getCreateTime(), LocalDateTimeUtils.NORMAL_DATETIME_FORMAT_NO_SECOND));
        return view;
    }

    /**
     * 根据活动和用户id查找某个人是否报名
     * @param userId 用户id
     * @param activityId 活动id
     * @return com.maixy.studyonlineapi.entity.Auth
     */
    public Auth findAuthByUserIdAndActivityId(Long userId, Long activityId) {
        return authMapper.selectOne(new QueryWrapper<Auth>()
                .lambda()
                .eq(Auth::getHasDelete, false)
                .eq(Auth::getCreateBy, userId)
                .eq(Auth::getActivityId, activityId)
                .orderByDesc(Auth::getCreateTime)
                .last("limit 1"));
    }

    /**
     * 查找一个课程的报名人数
     *
     * @param activityId 活动id
     * @return java.lang.Integer
     */
    public Integer findAuthNumByActivityId(Long activityId) {
        return authMapper.selectCount(new QueryWrapper<Auth>()
                .lambda()
                .eq(Auth::getActivityId, activityId)
                .eq(Auth::getHasDelete, false));
    }

    /**
     * 查找一个人加入课程数量
     *
     * @param useId 活动id
     * @return java.lang.Integer
     */
    public Integer countAuthNum(Long useId) {
        return authMapper.getAuthNum(useId);
    }

    /**
     * 根据查看一个学生报名老师的所有课程并且退出
     * @param teacherId 老师id
     * @param studentId 学生id
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void findAuthByTeacherIdAndStudentId(Long teacherId, Long studentId) {
        List<Auth> authList = authMapper.findAuthByTeacherIdAndStudentId(teacherId, studentId);
        //退出所有课程
        for (Auth auth : authList) {
            auth.setUpdateBy(studentId);
            auth.setUpdateTime(System.currentTimeMillis());
            auth.setHasDelete(true);
            update(auth);
        }
    }
}
